package com.skyd.core.android.game;

/**
 * 游戏动画，用于表示逐帧动画
 * 
 * @author SkyD
 * 
 */
public class GameAnimation extends GameNodeObject implements IGameImageHolder {
	
	public GameAnimation(){
		
	}
	
	public GameAnimation(GameAnimationFrame ... frames){
		for(GameAnimationFrame f: frames){
			try {
				f.setParent(this);
			} catch (GameException e) {
				e.printStackTrace();
			}
			getFrameList().add(f);
		}
	}
	
	/**
	 * 初始值为new GameObjectList<GameAnimationFrame>(this)。 功能注释：帧列表
	 */
	private GameObjectList<GameAnimationFrame> _FrameList = new GameObjectList<GameAnimationFrame>(
			this);

	/**
	 * 获取FrameList。 功能注释：帧列表
	 * 
	 * @return 当前的GameObjectList<GameAnimationFrame>类型的值
	 */
	public GameObjectList<GameAnimationFrame> getFrameList() {
		return _FrameList;
	}

	/**
	 * 设置FrameList。 功能注释：帧列表
	 * 
	 * @param value
	 *            要设置的GameObjectList<GameAnimationFrame>类型值
	 */
	protected void setFrameList(GameObjectList<GameAnimationFrame> value) {
		_FrameList = value;
	}

	/**
	 * 设置FrameList为其默认值(new GameObjectList<GameAnimationFrame>(this))。 功能注释：帧列表
	 */
	protected void setFrameListToDefault() {
		setFrameList(new GameObjectList<GameAnimationFrame>(this));
	}

	/**
	 * 初始值为-1。 功能注释：当前显示的帧索引位置，当动画未执行时，此值为-1
	 */
	private int _DisplayFrameIndex = -1;

	/**
	 * 获取DisplayFrameIndex。 功能注释：当前显示的帧索引位置，当动画未执行时，此值为-1
	 * 
	 * @return 当前的int类型的值
	 */
	public int getDisplayFrameIndex() {
		return _DisplayFrameIndex;
	}

	/**
	 * 设置DisplayFrameIndex。 功能注释：当前显示的帧索引位置，当动画未执行时，此值为-1
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	public void setDisplayFrameIndex(int value) {
		_DisplayFrameIndex = value;
	}

	/**
	 * 设置DisplayFrameIndex为其默认值(-1)。 功能注释：当前显示的帧索引位置，当动画未执行时，此值为-1
	 */
	public void setDisplayFrameIndexToDefault() {
		setDisplayFrameIndex(-1);
	}

	/**
	 * 获取当前显示的帧的图像
	 * 
	 * @return
	 */
	public GameImage getDisplayImage() {
		return getDisplayFrame().getImage();
	}

	/**
	 * 获取当前显示帧
	 * 
	 * @return
	 */
	public GameAnimationFrame getDisplayFrame() {
		return _FrameList.get(_DisplayFrameIndex);
	}

	/**
	 * 初始值为0。 功能注释：游戏帧计数，用于控制动画帧步进
	 */
	private int _FrameCounting = 0;

	/**
	 * 获取FrameCounting。 功能注释：游戏帧计数，用于控制动画帧步进
	 * 
	 * @return 当前的int类型的值
	 */
	public int getFrameCounting() {
		return _FrameCounting;
	}

	/**
	 * 设置FrameCounting。 功能注释：游戏帧计数，用于控制动画帧步进
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	protected void setFrameCounting(int value) {
		_FrameCounting = value;
	}

	/**
	 * 设置FrameCounting为其默认值(0)。 功能注释：游戏帧计数，用于控制动画帧步进
	 */
	protected void setFrameCountingToDefault() {
		setFrameCounting(0);
	}

	/**
	 * 初始值为0。 功能注释：循环播放次数计数
	 */
	private int _LoopCounting = 0;

	/**
	 * 获取LoopCounting。 功能注释：循环播放次数计数
	 * 
	 * @return 当前的int类型的值
	 */
	public int getLoopCounting() {
		return _LoopCounting;
	}

	/**
	 * 设置LoopCounting。 功能注释：循环播放次数计数
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	protected void setLoopCounting(int value) {
		_LoopCounting = value;
	}

	/**
	 * 设置LoopCounting为其默认值(0)。 功能注释：循环播放次数计数
	 */
	protected void setLoopCountingToDefault() {
		setLoopCounting(0);
	}

	/**
	 * 更新动画状态，如果动画处于停止状态，则不执行任何操作。每次执行此函数既表示游戏前进了1帧，此时动画就会根据游戏帧数调整为其应显示的帧位置。
	 */
	public void updateSelf() {
		super.updateSelf();
		if (!_IsRunning)
			return;
		if (++_FrameCounting >= getDisplayFrame().getDuration()) {
			nextFrame();
		}
	}

	@Override
	protected void updateChilds() {
		if (getIsRunning())
			super.updateChilds();
	}

	@Override
	public GameObject getDisplayContentChild() {
		return getDisplayFrame();
	}

	/**
	 * 初始值为-1。 功能注释：指示该动画的循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 */
	private int _LoopTime = -1;

	/**
	 * 获取LoopTime。 功能注释：指示该动画的循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 * 
	 * @return 当前的int类型的值
	 */
	public int getLoopTime() {
		return _LoopTime;
	}

	/**
	 * 设置LoopTime。 功能注释：指示该动画的循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 * 
	 * @param value
	 *            要设置的int类型值
	 */
	public void setLoopTime(int value) {
		_LoopTime = value;
	}

	/**
	 * 设置LoopTime为其默认值(-1)。
	 * 功能注释：指示该动画的循环次数，-1为无限循环，0为不循环，即只播放一次，大于0则表示播放一次后再播放的次数
	 */
	public void setLoopTimeToDefault() {
		setLoopTime(-1);
	}

	/**
	 * 显示下一帧，如果已经是末尾帧且未达到循环次数限制，则跳回第一帧
	 */
	public void nextFrame() {
		_FrameCounting = 0;
		if (++_DisplayFrameIndex >= _FrameList.size()) {
			if (_LoopTime < 0 || _LoopCounting++ < _LoopTime) {
				_DisplayFrameIndex = 0;
			} else
				stop();
		}
	}

	/**
	 * 从第一帧开始重新播放，所有计数归零重启
	 */
	public void restart() {
		_FrameCounting = 0;
		_DisplayFrameIndex = 0;
		_LoopCounting = 0;
		start();
	}

	/**
	 * 开始播放动画，首次播放或从停止状态中恢复播放时执行此函数
	 */
	public void start() {
		if (_DisplayFrameIndex == -1)
			_DisplayFrameIndex = 0;
		_IsRunning = true;
	}

	/**
	 * 动画停在当前帧，暂停播放
	 */
	public void stop() {
		_IsRunning = false;
	}

	/**
	 * 初始值为false。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 */
	private boolean _IsRunning = false;

	/**
	 * 获取IsRunning。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 * 
	 * @return 当前的boolean类型的值
	 */
	public boolean getIsRunning() {
		return _IsRunning;
	}

	/**
	 * 设置IsRunning。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 * 
	 * @param value
	 *            要设置的boolean类型值
	 */
	protected void setIsRunning(boolean value) {
		_IsRunning = value;
	}

	/**
	 * 设置IsRunning为其默认值(false)。 功能注释：指示动画是否在播放中，当未运行、执行了停止函数或达到循环次数上限时改值为false
	 */
	protected void setIsRunningToDefault() {
		setIsRunning(false);
	}

	/**
	 * 重设动画的总时间（游戏帧数），将根据新时间按比例重新设置每帧的持续时间
	 * 
	 * @param duration
	 *            新的总持续时间
	 */
	public void setTotalDuration(int duration) {
		float t = getTotalDuration() * 1.00f / duration;
		for (GameAnimationFrame f : _FrameList) {
			f.setDuration(Math.round(f.getDuration() * t));
		}
	}

	/**
	 * 获取动画的总持续时间（游戏帧数）
	 * 
	 * @return 动画的总持续时间
	 */
	public int getTotalDuration() {
		int t = 0;
		for (GameAnimationFrame f : _FrameList) {
			t += f.getDuration();
		}
		return t;
	}
}
